//
// Copyright (c) 2011 Alex Nesterenko
//

#include <execinfo.h>

#include <algorithm>
#include <cstdlib>

namespace nane
{
    ////////////////////////////////////////////////////////////////////////////////////////////////
    static const int c_maxBacktrace = 64;
    ////////////////////////////////////////////////////////////////////////////////////////////////
    uint32 GetStackFrames( StackFrame** _stackFrames, uint32 _count )
    {
        void* tracePtrs[c_maxBacktrace];
        int backtraceCaptured = backtrace(tracePtrs, std::min(static_cast<int>(_count), c_maxBacktrace));
        *_stackFrames = new StackFrame[backtraceCaptured+2];
        for( int i = 0; i < backtraceCaptured; ++i )
        {
            (*_stackFrames)[i].address = tracePtrs[i];
            (*_stackFrames)[i].text = NULL;
        }
        (*_stackFrames)[backtraceCaptured].address = NULL;
        (*_stackFrames)[backtraceCaptured].text = NULL;
        (*_stackFrames)[backtraceCaptured+1].address = NULL;
        (*_stackFrames)[backtraceCaptured+1].text = NULL;
        
        char** symbols = backtrace_symbols(tracePtrs, backtraceCaptured);
        if( symbols != NULL )
        {
            for( int i = 0; i < backtraceCaptured; ++i )
            {
                (*_stackFrames)[i].text = symbols[i];
            }
            (*_stackFrames)[backtraceCaptured+1].text = reinterpret_cast<char*>(symbols);
        }
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////
    void FreeStackFrames( StackFrame* _stackFrames )
    {
        StackFrame* stackFrame = _stackFrames;
        while( stackFrame->address != NULL )
        {
            ++stackFrame;
        }
        ++stackFrame;
        free(stackFrame->text);
        delete[] _stackFrames;
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////
}   // namespace nane
